/* 1. data.ok 发生变化的时候  执行分支也会发生改变 分支切换
   思路： 每次副作用函数执行时， 可以先把它从所有与之关联的依赖集合中删除 
   - 1 执行完毕后 会建立新的联系 新的联系不包含遗留的副作用函数 -> 副作用函数执行前 删除相关依赖  
   - 1.1 执行前 删除依赖 执行过程中 建立依赖 执行完毕 根据当前的变量进行构建依赖 
   - 2 重新 设计副作用函数  effect 函数内部 定义新的 effectFn函数 添加的deps属性 deps存储 存储 所有包含当前副作用函数的依赖集合

*/
const bucket = new WeakMap()
const obj = { ok: true, text: '巨旭', foo: 1 }
let activeEffect = null 
const effect = (fn) => {
    const effectFn = () => {
        clearup(effectFn)
        activeEffect = effectFn
        fn()
    }
    effectFn.deps = []
    effectFn()
}
const clearup = (effectFn) => {
    for (let i = 0; i < effectFn.deps.length; i++) {
        const deps = effectFn.deps[i]
        deps.delete(effectFn)
    }
    effectFn.deps.length = 0
}
const track = (target, key) => {
    let depsMap = bucket.get(target)
    if (!depsMap) bucket.set(target, depsMap = new Map())
    let deps = depsMap.get(key)
    if (!deps) depsMap.set(key, deps = new Set())
    deps.add(activeEffect)
    activeEffect.deps.push(deps)
} 
const trigger = (target, key) => {
    console.log("trigger")
    const depsMap = bucket.get(target)
    if (!depsMap) return true
    const effects = depsMap.get(key)
    // effects && effects.forEach(fn => fn())
    // 找一个方法 能在foreach 里面进行 delete add 
    const effectsToRun = new Set(effects)
    // 收集到的fn 执行  fn执行  会重新建立依赖关系 删除 添加 删除 添加
    effectsToRun && effectsToRun.forEach(fn => fn());
}
const data = new Proxy(obj, {
    get(target, key) {
        if (!activeEffect) return target[key]
        // 追踪的核心 
        track(target, key)
        return target[key]
    },
    set(target, key, newVale) {
        target[key] = newVale
        // 触发的逻辑
        trigger(target, key)
    }   
})
// 调用effect函数进行注册
effect(() => {
    document.body.innerText = data.ok ? data.text : 'not in'
})
setTimeout(() => {
    data.ok = false
    console.log(bucket,'bucket')
}, 2000)